#include "Core/Define/Define.h"
#include "Core/Error/Error.h"
#include "Core/Memory/MemoryPoolManager.h"
#include "Core/Log/LogConsole.h"
#include "Core/Log/LogFile.h"
#include "Core/Log/LogManager.h"
#include "Core/Profile/Profiler.h"
#include "Core/Profile/CodeProfile.h"
#include "Core/Thread/ThreadManager.h"
#include "Test/UnitTest.h"
#include "Test/MemoryTest.h"
#include "Test/URITest.h"
#include "Test/FileTest.h"
#include "Test/NotificationTest.h"
#include "Test/ThreadTest.h"
#include "Test/XMLTest.h"
#include "Test/PluginTest.h"
#include "Test/NetworkTest.h"
#include "Test/GUITest.h"

//#include "SpeedTest/SpeedTest.h"
//#include "SpeedTest/ArraySpeedTest.h"
//#include "SpeedTest/MemorySpeedTest.h"
#include <vector>

#include "Math/3D/Vector3D.h"
#include "Math/3D/Quaternion.h"

#include "Core/Notification/NotificationManager.h"
#include "Core/Plugin/PluginManager.h"

#ifdef WIN32
#pragma comment( lib, "comctl32.lib") 
#include <commctrl.h >
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture = '*' publicKeyToken = '6595b64144ccf1df' language = '*'\"")
#endif

int main(int argc, char *argv[])
{
	Core::Profile::Profiler::GetInstance().SetOutputFilename("../data/UnitTests.profile");
	
	{
		PROFILE("main");
		// Output log declarations
		Core::Log::LogFile lFile("../data/UnitTests.log");
		//LogConsole lConsole;


		std::cout << "- MAIN TEST -" << std::endl;

		std::vector<UnitTest*> pTests;
		pTests.push_back(new MemoryTest);
		pTests.push_back(new URITest);
		pTests.push_back(new FileTest);
		pTests.push_back(new NotificationTest);
		pTests.push_back(new ThreadTest);
		pTests.push_back(new XMLTest);
		pTests.push_back(new PluginTest);
		pTests.push_back(new NetworkTest);
		pTests.push_back(new GUITest(argc, argv));

		for (uint32 i = 0; i < pTests.size(); ++i)
		{
			if (Failed(pTests[i]->Create()))
			{
				std::cout << "- " << pTests[i]->GetName() << " : Creation failed !" << std::endl;
				break;
			}
			if (Failed(pTests[i]->Execute()))
			{
				std::cout << "- " << pTests[i]->GetName() << " : Execution failed !" << std::endl;
				break;
			}
			if (Failed(pTests[i]->Destroy()))
			{
				std::cout << "- " << pTests[i]->GetName() << " : Destroying failed !" << std::endl;
				break;
			}

			std::cout << "- " << pTests[i]->GetName() << " : OK" << std::endl;

			delete pTests[i];
		}

		std::cout << "- END -" << std::endl;

		/*LOG_INFO("- SPEED TEST -");

		std::vector<SpeedTest*> pSpeedTests;
		pSpeedTests.push_back(new ArraySpeedTest);
		pSpeedTests.push_back(new MemorySpeedTest);

		for(uint32 i=0; i<pSpeedTests.size(); ++i)
		{
		LOG_INFO("- %s", pSpeedTests[i]->GetName());
		pSpeedTests[i]->Execute();
		delete pSpeedTests[i];
		}

		LOG_INFO("- END -");*/

		Core::Thread::ThreadManager::GetInstance().Clear();
		Core::Memory::MemoryPoolManager::GetInstance().CheckLeaks(false);
	
	}

	Core::Plugin::PluginManager::DeleteInstance();
	Core::Notification::NotificationManager::DeleteInstance();
	Core::Thread::ThreadManager::DeleteInstance();
	Core::Log::LogManager::DeleteInstance();
	Core::Memory::MemoryPoolManager::DeleteInstance();
	Core::Profile::Profiler::DeleteInstance();

	return 0;
}
